public class Main {
    public static void main1(String[] args) {
        System.out.println("Hello world!");
        String s = "hello";
        System.out.println(s);
        StringBuffer stringBuffer = new StringBuffer();
        // ****异常****
        // 异常的概念
        //将程序执行过程中发生不正常的行为称之为异常
        //1. 算术异常
        //System.out.println(10 / 0);
        // // 执行结果
        //Exception in thread "main" java.lang.ArithmeticException: / by zero
        //ArithmeticException算数异常

        //2. 数组越界异常
        //int[] arr = {1, 2, 3};
        // System.out.println(arr[100]);
        // // 执行结果
        //Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100
        //ArrayIndexOutOfBoundsException 数组越界异常

        // 3. 空指针异常
        //int[] arr = null;
        // System.out.println(arr.length);
        // // 执行结果
        //Exception in thread "main" java.lang.NullPointerException
        //NullPointerException空指针异常



        // 当程序出现异常之后，将不会再继续执行异常之后的代码
        //，java中不同类型的异常，都有与其对应的类来进行描述。

        //异常的本质上就是一个类

        //1.2 异常的分类
        //1. 编译时异常
        //在程序编译期间发生的异常，称为编译时异常，也称为受检查异常(Checked Exception
        //2. 运行时异常
        //在程序执行期间发生的异常，称为运行时异常，也称为非受检查异常(Unchecked Exception)
        // RunTimeException以及其子类对应的异常，都称为运行时异常。比如：NullPointerException、
        //ArrayIndexOutOfBoundsException、ArithmeticException


        //2.异常的处理
        // 捕获异常
       /* try{
            // 存放可能存在异常的代码
        }catch (捕获具体的异常){

        }finally{

        }*/


        //异常的抛出
        // throw throws
        // 1.某段程序 触发
        // 2.通过关键字throw抛出异常
        //throw new XXXException("异常产生的原因");
        int a = 10;
        if(a == 10){
            throw  new NullPointerException("hahaha!");
        }//这个异常是由我们手动抛出的  这个关键字一般用于抛出我们自定义的异常
        //【注意事项】
        //1. throw必须写在方法体内部
        //2. 抛出的对象必须是Exception 或者 Exception 的子类对象(抛出的一定是一个异常)
        //3. 如果抛出的是 RunTimeException 或者 RunTimeException 的子类，则可以不用处理，直接交给JVM来处理
        //4. 如果抛出的是编译时异常，用户必须处理，否则无法通过编译
        //5. 异常一旦抛出，其后的代码就不会执行

        //throws使用再方法的声明之后
        // 作用：告诉方法的调用这，调用这个方法有可能会抛出一个XXXX异常
        // 在方法之后加了throws就不会被报错了
        // 如果一个方法内部 存在一个编译时异常（受查异常），此时这个编译时异常一定要进行处理
        // 目前我们处理的

        //2.3.1 异常声明throws
        //处在方法声明时参数列表之后，当方法中抛出编译时异常，用户不想处理该异常，此时就可以借助throws将异常抛
        //给方法的调用者来处理。即当前方法不处理异常，提醒方法的调用者处理异常
        //语法格式：
        //修饰符  返回值类型   方法名(参数列表) throws 异常类型1，异常类型2...{
        //
        //}

        //【注意事项】
        //1. throws必须跟在方法的参数列表之后
        //2. 声明的异常必须是 Exception 或者 Exception 的子类
        //3. 方法内部如果抛出了多个异常，throws之后必须跟多个异常类型，之间用逗号隔开，如果抛出多个异常类型
        //具有父子关系，直接声明父类即可。
        //4. 调用声明抛出异常的方法时，调用者必须对该异常进行处理，或者继续使用throws抛出


        //2.3.2 try-catch捕获并处理
        //throws对异常并没有真正处理，而是将异常报告给抛出异常方法的调用者，由调用者处理。如果真正要对异常进行
        //处理，就需要try-catch。
        //语法格式：
        //try{
        //   // 将可能出现异常的代码放在这里
        //}catch(要捕获的异常类型  e){
        //      // 如果try中的代码抛出异常了，此处catch捕获时异常类型与try中抛出的异常类型一致时，或者是try中抛出异常的基类
        //时，就会被捕获到
        //      // 对异常就可以正常处理，处理完成后，跳出try-catch结构，继续执行后序代码
        //}[catch(异常类型 e){
        //     // 对异常进行处理
        //}finally{
        //       // 此处代码一定会被执行到
        //}]
        //
        //// 后序代码
        //// 当异常被捕获到时，异常就被处理了，这里的后序代码一定会执行
        //// 如果捕获了，由于捕获时类型不对，那就没有捕获到，这里的代码就不会被执行
        //
        //注意：
        //  1. []中表示可选项，可以添加，也可以不用添加
        //  2. try中的代码可能会抛出异常，也可能不会

        //【注意事项】
        //1. try块内抛出异常位置之后的代码将不会被执行
        //2. 如果抛出异常类型与catch时异常类型不匹配，即异常不会被成功捕获，也就不会被处理，继续往外抛，直到
        //JVM收到后中断程序----异常是按照类型来捕获的
        //3. try中可能会抛出多个不同的异常对象，则必须用多个catch来捕获----即多种异常，多次捕获
        //4. 可以通过一个catch捕获所有的异常，即多个异常，一次捕获(不推荐)

    }

    public static void main(String[] args) {
       // System.out.println(10/0);  //这种就是交给jvm处理了，一旦交给jvm处理程序就会立即终止
        System.out.println("after.......");
        try {
            System.out.println(10/0);
        }catch (ArithmeticException e) {
            System.out.println("我来处理异常了");
        }
        //由于 Exception 类是所有异常类的父类. 因此可以用这个类型表示捕捉所有异常.
        // 2.3.3 finally
        //在写程序时，有些特定的代码，不论程序是否发生异常，都需要执行，比如程序中打开的资源：网络连接、数据库
        //连接、IO流等，在程序正常或者异常退出时，必须要对资源进进行回收。另外，因为异常会引发程序的跳转，可能
        //导致有些语句执行不到，finally就是用来解决这个问题的。
        //语法格式：
        //try{
        //   // 可能会发生异常的代码
        //}catch(异常类型  e){
        //   // 对捕获到的异常进行处理
        //}finally{
        //   // 此处的语句无论是否发生异常，都会被执行到
        //}
        //
        //// 如果没有抛出异常，或者异常被捕获处理了，这里的代码也会执行
        //finally中的代码一定会执行的，一般在finally中进行一些资源清理的扫尾工作。
        //
    }
}